//
//  FatherTableViewCell.swift
//  KeDaLeDaoHang
//
//  Created by 陈钟 on 2019/5/13.
//  Copyright © 2019 陈钟. All rights reserved.
//

import UIKit

open class FatherTableHeaderFooterView: UITableViewHeaderFooterView{
    public override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)
        self.createView()
    }

    required public init?(coder: NSCoder) {
        super.init(coder: coder)
        self.createView()
    }
    
    open override func awakeFromNib() {
        super.awakeFromNib()
        self.createView()
    }

    open func createView() { }
}

open class FatherTableViewCell: UITableViewCell {
    
    override open func awakeFromNib() {
        super.awakeFromNib()
        self.createView()
    }

    override open func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

    override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.createView()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.createView()
    }
    
    open var superTable: UITableView?
    open var indexPath: IndexPath?
    
    open func createView() { }
    
}

open class FatherCollectionViewCell: UICollectionViewCell {
    override public init(frame: CGRect) {
        super.init(frame: frame)
        createView()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        createView()
    }
    
    override open func awakeFromNib() {
        super.awakeFromNib()
        self.createView()
    }
    open func createView() { }
}

open class FatherCollectionHeaderFooterView: UICollectionReusableView{
    public override init(frame: CGRect) {
        super.init(frame: frame)
        createView()
    }

    required public init?(coder: NSCoder) {
        super.init(coder: coder)
        createView()
    }
    
    override open func awakeFromNib() {
        super.awakeFromNib()
        self.createView()
    }
    
    open func createView() { }

}


public extension UITableView{
    
    @discardableResult
    func register<T>(cell cellClass: T.Type, nibName: String? = nil, identifier: String = "\(NSStringFromClass(T.self))_identifier") -> Self where T: UITableViewCell{
        guard let nib_name = nibName else {
            self.register(cellClass, forCellReuseIdentifier: identifier )
            return self
        }
        self.register(UINib(nibName: nib_name, bundle: nil), forCellReuseIdentifier: identifier)
        return self
    }
    
    @discardableResult
    func register<T>(headerFooter cellClass: T.Type, nibName: String? = nil, identifier: String = "\(NSStringFromClass(T.self))_identifier") -> Self where T: UITableViewHeaderFooterView{
        guard let nib_name = nibName else {
            self.register(cellClass, forHeaderFooterViewReuseIdentifier: identifier )
            return self
        }
        self.register(UINib(nibName: nib_name, bundle: nil), forHeaderFooterViewReuseIdentifier: identifier)
        return self
    }
    
    func defaultCell(_ style:UITableViewCell.CellStyle = .default, initBlock: ((_ cell: UITableViewCell) -> Void)? = nil) -> UITableViewCell {
        let cell = self.cellT(identifier: "ZZUITableViewCell_Default",
                              cellClass: UITableViewCell.self,
                              style: style,
                              initBlock: { (init_cell) in
                                initBlock?(init_cell)
        })
        return cell
    }
    
    func cellT<T: UITableViewCell>(identifier: String = "\(NSStringFromClass(T.self))_identifier",
                  cellClass:T.Type,
                  for indexPath: IndexPath) -> T{
        let cell = self.dequeueReusableCell(withIdentifier: identifier, for: indexPath) as! T
        return cell
    }
    
    func cellT<T: UITableViewCell>(identifier: String = "\(NSStringFromClass(T.self))_identifier",
                  cellClass:T.Type,
                  style:UITableViewCell.CellStyle = .default,
                  initBlock:((_ cell:T) -> Void)? = nil) -> T{
        var cell = self.dequeueReusableCell(withIdentifier: identifier)
        if cell == nil {
            cell = cellClass.init(style: style, reuseIdentifier: identifier)
            if initBlock != nil { initBlock!(cell as! T) }
        }
        return cell as! T
    }

    func headerFooterView<T: UITableViewHeaderFooterView>(identifier: String = "\(NSStringFromClass(T.self))HeaderFooter_identifier",
        headerFooterClass: T.Type,
        initBlock:((_ cell:T) -> Void)? = nil) -> T{
        var view = self.dequeueReusableHeaderFooterView(withIdentifier: identifier)
        if view == nil {
            view = headerFooterClass.init(reuseIdentifier: identifier)
            if initBlock != nil { initBlock!(view as! T) }
        }
        return view as! T
    }
}

public extension UICollectionView{
    @discardableResult
    func register<T>(cell cellClass: T.Type, nibName: String? = nil, identifier: String = "\(NSStringFromClass(T.self))_identifier") -> Self where T: UICollectionViewCell{
        guard let nib_name = nibName else {
            self.register(cellClass, forCellWithReuseIdentifier: identifier)
            return self
        }
        self.register(UINib(nibName: nib_name, bundle: nil), forCellWithReuseIdentifier: identifier)
        return self
    }
    
    @discardableResult
    func register<T>(header headerClass: T.Type, nibName: String? = nil, identifier: String = "\(NSStringFromClass(T.self))_identifier") -> Self where T: UICollectionReusableView{
        guard let nib_name = nibName else {
            self.register(headerClass, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: identifier)
            return self
        }
        self.register(UINib(nibName: nib_name, bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: identifier)
        return self
    }
    
    @discardableResult
    func register<T>(footer headerClass: T.Type, nibName: String? = nil, identifier: String = "\(NSStringFromClass(T.self))_identifier") -> Self where T: UICollectionReusableView{
        guard let nib_name = nibName else {
            self.register(headerClass, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: identifier)
            return self
        }
        self.register(UINib(nibName: nib_name, bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: identifier)
        return self
    }

    func cell<T: UICollectionViewCell>(_ identifier: String = "\(NSStringFromClass(T.self))_identifier",
                 cellClass: T.Type,
                 indexPath: IndexPath) -> T {
        let cell = self.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)
        return cell as! T
    }
    
    func dequeueReusableSupplementaryView<T: UICollectionReusableView>(ofKind elementKind: String, withReuseIdentifier identifier: String = "\(NSStringFromClass(T.self))_identifier", for indexPath: IndexPath, classType: T.Type) -> T{
        return self.dequeueReusableSupplementaryView(ofKind: elementKind,
                                                     withReuseIdentifier: identifier,
                                                     for: indexPath) as! T
    }

    func headerView<T: UICollectionReusableView>(_ classType: T.Type, for indexPath: IndexPath, identifier: String = "\(NSStringFromClass(T.self))_identifier") -> T{
        return self.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader,
                                                     withReuseIdentifier: identifier,
                                                     for: indexPath,
                                                     classType: classType)
    }

    func footerView<T: UICollectionReusableView>(_ classType: T.Type, for indexPath: IndexPath, identifier: String = "\(NSStringFromClass(T.self))_identifier") -> T{
        return self.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionFooter,
                                                     withReuseIdentifier: identifier,
                                                     for: indexPath,
                                                     classType: classType)
    }
}
